package com.xinxing.learning.datasource.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.xinxing.learning.datasource.config.DataSourceCachePool;
import com.xinxing.learning.datasource.model.DynamicDataSourceModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Objects;

@Slf4j
public class DynamicDBUtil {

    public static synchronized DruidDataSource getDbSourceByDbKey(String dbKey) {
        DruidDataSource cacheDbSource = DataSourceCachePool.getCacheBasicDataSource(dbKey);
        if (Objects.nonNull(cacheDbSource) && cacheDbSource.isEnable()) {
            return cacheDbSource;
        }

        DynamicDataSourceModel dynamicDataSourceModel = DataSourceCachePool.getCacheDynamicDataSourceModel(dbKey);
        DruidDataSource dataSource = getJdbcDataSource(dynamicDataSourceModel);

        if (Objects.nonNull(dataSource) && dataSource.isEnable()) {
            DataSourceCachePool.putCacheBasicDataSource(dbKey, dataSource);
        }

        return dataSource;
    }

    private static DruidDataSource getJdbcDataSource(DynamicDataSourceModel dataSourceModel) {
        DruidDataSource dataSource = new DruidDataSource();

        String driverClassName = dataSourceModel.getDbDriver();
        String url = dataSourceModel.getDatasourceUrl();
        String dbUser = dataSourceModel.getDatasourceAccount();
        String dbPassword = dataSourceModel.getDatasourcePassword();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(dbUser);
        dataSource.setPassword(dbPassword);
        dataSource.setMaxWait(60000);
        //dataSource.setValidationQuery("SELECT 1 FROM DUAL");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        dataSource.setBreakAfterAcquireFailure(true);
        dataSource.setConnectionErrorRetryAttempts(0);

        log.info("******************************************");
        log.info("*                                        *");
        log.info("*====【" + dataSourceModel.getDatasourceName() + "】=====Druid连接池已启用 ====*");
        log.info("*                                        *");
        log.info("******************************************");
        return dataSource;
    }

    public static void closeDbKey(String dbKey) {
        DruidDataSource druidDataSource = DynamicDBUtil.getDbSourceByDbKey(dbKey);
        try {
            if (Objects.nonNull(druidDataSource) && druidDataSource.isEnable()) {
                druidDataSource.getConnection().commit();
                druidDataSource.getConnection().close();
                druidDataSource.close();
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

    public static JdbcTemplate getJdbcTemplate(String dbKey) {
        DruidDataSource dataSource = DynamicDBUtil.getDbSourceByDbKey(dbKey);
        return new JdbcTemplate(dataSource);
    }

    /**
     * 获取连接
     *
     * @param url
     * @param username
     * @param password
     * @param driverName
     * @return
     */
    public static Connection getConn(String url, String username, String password, String driverName) {
        Connection conn = null;
        try {
            Class.forName(driverName);
            conn = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            throw new RuntimeException("无法连接，问题：" + e.getMessage(), e);
        }

        return conn;
    }

    /**
     * 关闭数据库连接
     *
     * @param
     */
    public static void closeConnection(Connection conn) {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException("close connection failure", e);
        }
    }
}
